#include "pch.h"
#include "D2DManager.h"

using namespace D2D1;

D2DManager^ D2DManager::m_instance;

D2DManager::D2DManager()
{
	D2D1_FACTORY_OPTIONS options;
	ZeroMemory(&options, sizeof(D2D1_FACTORY_OPTIONS));

#if defined(_DEBUG)
	options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
#endif

	ThrowIfFailed(
		D2D1CreateFactory(
		D2D1_FACTORY_TYPE_MULTI_THREADED,
		__uuidof(ID2D1Factory2),
		&options,
		&m_d2dFactory
		)
		);

	ThrowIfFailed(
		CoCreateInstance(
		CLSID_WICImagingFactory2,
		nullptr,
		CLSCTX_INPROC_SERVER,
		IID_PPV_ARGS(&m_wicFactory)
		)
		);

	UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;

#if defined(_DEBUG)
	creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

	D3D_FEATURE_LEVEL featureLevels[] =
	{
		D3D_FEATURE_LEVEL_11_1,
		D3D_FEATURE_LEVEL_11_0,
		D3D_FEATURE_LEVEL_10_1,
		D3D_FEATURE_LEVEL_10_0,
		D3D_FEATURE_LEVEL_9_3,
		D3D_FEATURE_LEVEL_9_2,
		D3D_FEATURE_LEVEL_9_1
	};

	ComPtr<ID3D11Device> device;
	ComPtr<ID3D11DeviceContext> context;
	D3D_FEATURE_LEVEL featureLevel;

	ThrowIfFailed(
		D3D11CreateDevice(
		nullptr,
		D3D_DRIVER_TYPE_HARDWARE,
		0,
		creationFlags,
		featureLevels,
		ARRAYSIZE(featureLevels),
		D3D11_SDK_VERSION,
		&device,
		&featureLevel,
		&context
		)
		);

	ThrowIfFailed(
		device.As(&m_dxgiDevice)
		);

	m_dxgiDevice->SetMaximumFrameLatency(1);
	
	ThrowIfFailed(
		m_d2dFactory->CreateDevice(m_dxgiDevice.Get(), &m_d2dDevice)
		);

	ThrowIfFailed(
		m_d2dDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, &m_d2dDeviceContext)
		);

	if (!Windows::ApplicationModel::DesignMode::DesignModeEnabled)
	Application::Current->Suspending +=	ref new SuspendingEventHandler(this, &D2DManager::App_Suspending);
}

void D2DManager::App_Suspending(Object^ sender, SuspendingEventArgs^ e)
{
	m_dxgiDevice->Trim();
}

D2DManager^ D2DManager::GetInstance()
{
	if (m_instance == nullptr)
		m_instance = ref new D2DManager();

	return m_instance;
}